package com.easy.generator;


import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class TableToBeanGenerator {
    private static final String DRIVER = Easy.MYSQL_DRIVER;
    private static final String URL = Easy.MYSQL_URL;
    private static final String USER = Easy.MYSQL_USER;
    private static final String PASS = Easy.MYSQL_PASSWORD;
    private static final String DATABASE_NAME = Easy.MYSQL_DATABASE_NAME;

    private static final String DATE_PACKAGE_NAME = "java.util.Date";
    private static final String DATE_CLASS_NAME = "Date";
    private static final String BIGDECIMAL_PACKAGE_NAME = "java.math.BigDecimal";
    private static final String BIGDECIMAL_CLASS_NAME = "BigDecimal";

    public static void generate() {
        Easy.initPackage(Easy.BEAN_PACKAGE);
        try {
            Class.forName(DRIVER);
            Connection conn = DriverManager.getConnection(URL, USER, PASS);
            DatabaseMetaData metaData = conn.getMetaData();
            ResultSet tables = metaData.getTables(DATABASE_NAME, null, "%", new String[]{"TABLE"});
            while (tables.next()) {
                String tableName = tables.getString("TABLE_NAME");
                generateBeanClass(conn, tableName);
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void generateBeanClass(Connection conn, String tableName) throws SQLException, IOException {
        StringBuilder class_content = new StringBuilder();
        StringBuilder import_strb = new StringBuilder();
        StringBuilder class_strb = new StringBuilder();
        String className = toCamelCase(tableName, true);
        import_strb.append("package " + Easy.BEAN_PACKAGE + ";\n");
        class_strb.append("import com.baomidou.mybatisplus.annotation.*;\n");
        class_strb.append("import lombok.Data;\n");
        class_strb.append("@Data\n");
        class_strb.append("@TableName(\"" + tableName + "\")\n");
        class_strb.append("public class ").append(className).append(" {\n");
        ResultSet columns = conn.getMetaData().getColumns(null, null, tableName, null);
        List<String> fields = new ArrayList<>();
        int count = 0;
        while (columns.next()) {
            String columnName = columns.getString("COLUMN_NAME");
            String type = columns.getString("TYPE_NAME");
            String fieldName = toCamelCase(columnName, false);
            String javaType = getJavaType(type);
            if (javaType.equals(DATE_CLASS_NAME) ) {
                if (import_strb.indexOf(DATE_PACKAGE_NAME) == -1) {
                    import_strb.append("import " + DATE_PACKAGE_NAME + ";\n");
                    import_strb.append("import org.springframework.format.annotation.DateTimeFormat;\n");
                    import_strb.append("import com.fasterxml.jackson.annotation.JsonFormat;\n");
                }
                class_strb.append("    @DateTimeFormat(pattern = \"yyyy-MM-dd\")\n");
                class_strb.append("    @JsonFormat(pattern = \"yyyy-MM-dd\",timezone = \"GMT+8\")\n");
            }else if (javaType.equals(BIGDECIMAL_CLASS_NAME) && import_strb.indexOf(BIGDECIMAL_PACKAGE_NAME) == -1) {
                import_strb.append("import " + BIGDECIMAL_PACKAGE_NAME + ";\n");
            }
            if (count == 0)
                class_strb.append("    @TableId(value = \"").append(columnName).append("\",type = IdType.AUTO)\n");
            else
                class_strb.append("    @TableField(value= \"" + columnName + "\")\n");
            count++;
            class_strb.append("    private " + javaType + " " + fieldName + ";\n");
        }
        class_strb.append("}\n");
        class_content.append(import_strb);
        class_content.append(class_strb);

        String content = String.format(class_content.toString(), LocalDate.now());
        File outputFile = new File(Easy.PROJECT_ABSOLUTE_URL + Easy.SRC_DIR + Easy.convertPackagePath(Easy.BEAN_PACKAGE) + "/" + className + ".java");
        try (FileWriter writer = new FileWriter(outputFile)) {
            writer.write(content);
        }
    }

    private static String toCamelCase(String input, boolean capitalizeFirst) {
        String[] parts = input.split("_");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < parts.length; i++) {
            String part = parts[i].toLowerCase();
            if (i == 0 && !capitalizeFirst) {
                sb.append(part);
            } else {
                sb.append(part.substring(0, 1).toUpperCase())
                        .append(part.substring(1));
            }
        }
        return sb.toString();
    }

    private static String getJavaType(String sqlType) {
        switch (sqlType.toUpperCase()) {
            case "INT":
            case "INTEGER":
            case "MEDIUMINT":
                return "Integer";
            case "VARCHAR":
            case "CHAR":
            case "TEXT":
                return "String";
            case "DATE":
            case "DATETIME":
            case "TIMESTAMP":
                return "Date";
            case "DECIMAL":
            case "NUMERIC":
                return "BigDecimal";
            case "BOOLEAN":
            case "BIT":
                return "Boolean";
            case "BIGINT":
                return "Long";
            case "FLOAT":
                return "Float";
            case "DOUBLE":
                return "Double";
            case "TINYINT":
                return "Byte";
            case "SMALLINT":
                return "Short";
            case "BLOB":
                return "byte[]";
            default:
                return "Object";
        }
    }
}

